package com.example.master.utils;

import com.example.master.entity.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class JwtTokenUtil {
    @Value("${jwt.secret}")
    private String secret;// 密钥
    @Value("${jwt.expiration}")
    private Long expiration;
    /**
     *      生成token
     */
    public String generateToken(String phone) {
        String token = generateJwtToken(phone);
        return token;
    }
    String generateJwtToken(String phone) {
        // claim:Playload 里的申明部分
        Map<String, Object> claims = new HashMap<>(1);
        // 创建一个jwtbuilder负责构造一个jwt的对象，使用的是设计模式里的建造者模式(Builder)
        JwtBuilder jwtBuilder = Jwts.builder();

        jwtBuilder.setClaims(claims);
        // 设置claims的主题
        jwtBuilder.setSubject(phone);
        // 设置claims里的iat:签发的时间
        long iat = System.currentTimeMillis();
        log.info("iat:{}",iat);
        jwtBuilder.setIssuedAt(new Date(iat));
        // 设置claims里的exp：过期时间
        long exp = System.currentTimeMillis() + expiration;
        log.info("exp:{}",exp);
        jwtBuilder.setExpiration(new Date(exp));
        // 使用指定的算法进行签名，生成一个jws,         header中保存签名算法,
        jwtBuilder.signWith(SignatureAlgorithm.HS512, secret);
        //构建JWT并将其序列化为一个紧凑的、url安全的字符串
        String token = jwtBuilder.compact();
        return token;
    }
    /**
     * 从token中获取JWT中的负载
     */
    private Claims getClaimsFromToken(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            log.info("JWT格式验证失败:{}",token);
        }
        return claims;
    }
    public String getPhoneFromToken(String token) {
        String phone;
        try {
            Claims claims = getClaimsFromToken(token);
            phone =  claims.getSubject();
        } catch (Exception e) {
            phone = null;
        }
        return phone;
    }
    /**
     * 验证token是否还有效
     * @param token 客户端传入的token
     */
    public boolean validateToken(String token, User user) {
        String phone = getPhoneFromToken(token);
        return phone.equals(user.getPhone()) && !isTokenExpired(token);
    }
    /**
     * 判断token是否过期
     */
    public boolean isTokenExpired(String token) {
        Date expiredDate = getExpiredDateFromToken(token);
        return expiredDate.before(new Date());
    }
    /**
     * 从token中获取过期时间
     */
    private Date getExpiredDateFromToken(String token) {
        Claims claims = getClaimsFromToken(token);
        return claims.getExpiration();
    }


}
